package com.freek.ScreenDrop;

import java.awt.BasicStroke;
import java.awt.BorderLayout;
import java.awt.Canvas;
import java.awt.Color;
import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Point;
import java.awt.Rectangle;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.event.WindowEvent;

import javax.swing.JFrame;
import javax.swing.JPanel;

public class RegionSelectFrame extends JFrame
{
	
	public static final int HOOK_NEW = 0x1;
	public static final int HOOK_TOP = 0x2;
	public static final int HOOK_BOTTOM = 0x4;
	public static final int HOOK_LEFT = 0x8;
	public static final int HOOK_RIGHT = 0x10;
	public static final int HOOK_MOVE = 0x20;
	public static final int EDGE_TOLERANCE = 10;
	
	public static final int STROKE_WIDTH = 2;

	private JPanel contentPane;

	/**
	 * Launch the application.
	 */
	public static void main(String[] args)
	{
		EventQueue.invokeLater(new Runnable() {
			public void run()
			{
				try
				{
					RegionSelectFrame frame = new RegionSelectFrame();
					frame.setVisible(true);
				} catch (Exception e)
				{
					e.printStackTrace();
				}
			}
		});
	}

	Rectangle region;
	Canvas canvas;
	/**
	 * Create the frame.
	 */
	public RegionSelectFrame()
	{
		setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
		setUndecorated(true);
		setResizable(false);
		setBackground(new Color(0,0,0,1));
		setExtendedState(JFrame.MAXIMIZED_BOTH);
		contentPane = new JPanel();
		contentPane.setLayout(new BorderLayout());
		setContentPane(contentPane);
		
		region = null;
		
		canvas = new Canvas(){
			
			float[] dashPattern = {10f};
			BasicStroke dashed = new BasicStroke(STROKE_WIDTH, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER, 10, dashPattern,0);
			@Override
			public void paint(Graphics graphics)
			{
				super.paint(graphics);
				Graphics2D g = (Graphics2D) graphics;
				if(region != null)
				{
					Rectangle temp = absRect(region);
					g.setColor(new Color(0,0,0,127));
					g.fillRect(0,0,getWidth(),(int) temp.getY());
					g.fillRect(0, (int)(temp.getY()+temp.getHeight()), 
							getWidth(), (int) (getHeight()-(temp.getY()+temp.getHeight())));
					g.fillRect(0, (int)(temp.getY()), (int)(temp.getX()), (int) temp.getHeight());
					g.fillRect((int)(temp.getX()+temp.getWidth()),(int)temp.getY(),
							(int)(getWidth()-(temp.getX()+temp.getWidth())),(int) temp.getHeight());
				
					g.setStroke(dashed);
					g.setColor(new Color(255,0,0,127));
					g.drawRect(temp.x, temp.y, temp.width, temp.height);
					
					g.setColor(Color.white);
					g.drawString("Press Enter to upload", temp.x, temp.y+temp.height+15);
				}
				else
				{
					g.setColor(new Color(0,0,0,127));
					g.fillRect(0, 0, getWidth(), getHeight());
				}
			}
		};
		
		KeyListener quitListener = new KeyAdapter(){
			@Override
			public void keyReleased(KeyEvent e)
			{
				super.keyTyped(e);
				if(e.getKeyCode() == KeyEvent.VK_ESCAPE)
				{
					region = null;
					processWindowEvent(new WindowEvent(getWindows()[0],WindowEvent.WINDOW_CLOSING));
				}
			} 
		};
		canvas.addKeyListener(quitListener);
		this.addKeyListener(quitListener);
		
		MouseAdapter mouseListener = new MouseAdapter(){
			
			Point oldClick;
			int hook;
			@Override
			public void mousePressed(MouseEvent e)
			{
				super.mousePressed(e);
				
				oldClick = e.getPoint();
				if(region == null)
				{
					hook = HOOK_NEW;
					region = new Rectangle(e.getX(), e.getY(), 1, 1);
					return;
				}
				
				Rectangle inner = absRect(region);
				inner.grow(-EDGE_TOLERANCE,-EDGE_TOLERANCE);
				Rectangle top = absRect(region);
				top.y -= EDGE_TOLERANCE;
				top.height = EDGE_TOLERANCE*2;
				Rectangle bottom = absRect(region);
				bottom.y = bottom.y + bottom.height - EDGE_TOLERANCE;
				bottom.height = EDGE_TOLERANCE*2;
				Rectangle left = absRect(region);
				left.x -= EDGE_TOLERANCE;
				left.width = EDGE_TOLERANCE*2;
				Rectangle right = absRect(region);
				right.x = right.x + right.width - EDGE_TOLERANCE;
				right.width = EDGE_TOLERANCE*2;
				
				hook = 0;
				if(top.contains(e.getPoint()))
					hook |= HOOK_TOP;
				if(bottom.contains(e.getPoint()))
					hook |= HOOK_BOTTOM;
				if(left.contains(e.getPoint()))
					hook |= HOOK_LEFT;
				if(right.contains(e.getPoint()))
					hook |= HOOK_RIGHT;
				if(inner.contains(e.getPoint()))
					hook = HOOK_MOVE;
				if(hook == 0)
				{
					hook = HOOK_NEW;
					region.x = e.getX();
					region.y = e.getY();
					region.width = 1;
					region.height = 1;
				}
				
				repaint();
			}
			@Override
			public void mouseDragged(MouseEvent e)
			{
				int mx = e.getX();
				int my = e.getY();

				super.mouseDragged(e);
				if(hook == HOOK_NEW)
				{
					if((e.getModifiersEx() & MouseEvent.SHIFT_DOWN_MASK) != 0)
					{
						int width = Math.max(mx-region.x, my-region.y);
						mx = region.x+width;
						my = region.y+width;
						System.out.println(mx+" "+my);
					}
					region.width = mx - region.x;
					region.height = my - region.y;	
				}
				if(hook == HOOK_MOVE)
				{
					region.translate(mx-oldClick.x, my - oldClick.y);
				}
				if((hook & HOOK_TOP) != 0)
				{
					if(region.height>=0)
					{
					region.y += my - oldClick.y;
					region.height -= my - oldClick.y;
					}
					else
					{
						
					}
				}
				if((hook & HOOK_BOTTOM) != 0)
				{
					region.height += my - oldClick.y;
				}
				if((hook & HOOK_LEFT) != 0)
				{
					region.x += mx - oldClick.x;
					region.width -= mx - oldClick.x;
				}
				if((hook & HOOK_RIGHT) != 0)
				{
					region.width += mx - oldClick.x;
				}
				
				oldClick = e.getPoint();
				repaint();
			}
		};
		
		canvas.addMouseListener(mouseListener);
		canvas.addMouseMotionListener(mouseListener);
		
		contentPane.add(canvas,BorderLayout.CENTER);
		
		this.toFront();
	}

	public static Rectangle absRect(Rectangle r)
	{
		Rectangle temp = (Rectangle) r.clone();
		if(temp.width<0)
		{
			temp.width *= -1;
			temp.x -= temp.width;
		}
		if(temp.height<0)
		{
			temp.height *= -1;
			temp.y -= temp.height;
		}
		return temp;
	}
	
	private static Object lock = new Object();
	
	public static RegionSelectFrame selectRegion()
	{
		try
		{
			final RegionSelectFrame frame = new RegionSelectFrame();
			frame.setVisible(true);
			
			KeyAdapter enterListener = new KeyAdapter() {
				@Override
				public void keyReleased(KeyEvent e)
				{
					super.keyReleased(e);
					if(e.getKeyCode() == KeyEvent.VK_ENTER)
					{
						if(frame.region != null)
						{
							frame.processWindowEvent(new WindowEvent(getWindows()[0],WindowEvent.WINDOW_CLOSING));

						}
					}
				}
			};
			frame.addKeyListener(enterListener);
			frame.canvas.addKeyListener(enterListener);
			return frame;
		} catch (Exception e)
		{
			e.printStackTrace();
		}
		return null;
	}
}
